package com.fjwt.gz.task.log;

import com.fjwt.gz.core.aop.ScheduledLog;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * 定时任务日志切面
 * @author mei
 */
@Aspect
@Component
public class ScheduledLogAspect  {

    private static final Logger logger = LoggerFactory.getLogger(ScheduledLogAspect.class);

    @Autowired
    private TaskLogService taskLogService;

    @Autowired
    private Environment environment;

    @Around("@annotation(com.fjwt.gz.core.aop.ScheduledLog)")
    public Object aroundScheduledTask(ProceedingJoinPoint joinPoint) throws Throwable {
        // 获取方法信息
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        // 通过反射获取注解
        ScheduledLog scheduledLog = method.getAnnotation(ScheduledLog.class);

        String className = joinPoint.getTarget().getClass().getName();
        String methodName = method.getName();
        String fullMethodName = className + "." + methodName;

        // 解析cron表达式中的占位符
        String cronExpression = scheduledLog.cron();
        if (cronExpression.startsWith("${") && cronExpression.endsWith("}")) {
            String placeholder = cronExpression.substring(2, cronExpression.length() - 1);
            cronExpression = environment.getProperty(placeholder, cronExpression);
        }

        // 记录任务开始
        long logId = taskLogService.logTaskStart(
            scheduledLog.taskName(),
            fullMethodName,
            cronExpression
        );

        try {
            // 执行定时任务
            Object result = joinPoint.proceed();

            // 记录任务成功
            taskLogService.logTaskSuccess(logId);
            return result;
        } catch (Throwable throwable) {
            // 记录任务失败
            taskLogService.logTaskFailure(logId, throwable);
            // 继续抛出异常
            throw throwable;
        }
    }
}